```latex
\newcommand{\commonfolder}{../../common-files}

\input{\commonfolder/header}
\input{\commonfolder/copyright}

\newcommand{\rebindingFigs}{./Figs}

\lhead{\bfseries SEED Labs -- DNS Rebinding Attack Lab}


\begin{document}

\begin{center}
{\LARGE DNS Rebinding Attack Lab}
\end{center}

\seedlabcopyright{2019 - 2020}

\newcounter{task}
\setcounter{task}{1}
\newcommand{\tasks} {\bf {\noindent (\arabic{task})} \addtocounter{task}{1} \,}


% *******************************************
% SECTION
% ******************************************* 
\section{引言}


本次实验的目的是两方面的：(1) 展示 DNS 重绑定攻击的工作原理，以及 (2) 帮助学生获得亲自使用 DNS 重绑定技术攻击物联网设备的经验。在实验中，我们有一个模拟的物联网设备，可以通过网页界面进行控制（这对于许多 IoT 设备来说是典型的）。许多 IoT 设备没有强大的保护机制，如果攻击者可以直接与这些设备交互，他们可以很容易地破坏这些设备。

本次实验所模拟的 IoT 设备是一个恒温器，用来控制房间温度。要成功设置温度，客户端需要能够与 IoT 服务器进行互动。由于物联网设备在防火墙之后，外部机器无法与其互动，因此无法控制恒温器。为了击败防火墙保护，攻击代码必须首先进入内部网络。这并不困难：当内部网络的用户访问攻击者的网站时，攻击者的 JavaScript 代码实际上会在用户的浏览器中运行，并因此在受保护的内部网络内运行。然而，由于浏览器实现的安全沙盒保护措施，即使代码现在位于内部网络内，它仍然无法与 IoT 设备互动。

本次实验的目标是使用 DNS 重绑定攻击绕过安全沙盒保护，从而使攻击者的 JavaScript 代码可以从 IoT 设备获取关键信息，并利用这些信息将恒温器的温度设置为危险高的值。该实验涵盖了以下主题：

\begin{itemize}[noitemsep]
    \item DNS 服务器配置
    \item DNS 重绑定攻击
    \item 对物联网设备的攻击
    \item 同源策略
\end{itemize}

\paragraph{参考资料和视频。}
有关 DNS 协议及其攻击的详细资料可以在以下资源中找到：

\begin{itemize}
    \item SEED Book 第 18 章，\seedbook
    \item SEED 讲义第 7 节，\seedisvideo
\end{itemize}

\paragraph{实验环境。} \seedenvironmentC


% *******************************************
% SECTION
% ******************************************* 
\section{物联网背景}

我们的攻击目标是一个被防火墙保护的 IoT 设备。我们无法直接从外部访问这个 IoT 设备。我们的目标是让内部用户运行我们的 JavaScript 代码，然后使用 DNS 重绑定攻击与 IoT 设备互动。

许多 IoT 设备内置了一个简单的 Web 服务器，因此用户可以使用 Web API 来与其进行互动。通常这些物联网设备受到防火墙的保护，无法直接从外部访问它们。由于这种类型的保护机制，许多 IoT 设备并没有实现强大的身份验证机制。如果攻击者能够找到与这些设备互动的方法，他们可以轻易地破坏其安全性。

我们通过一个简单的 Web 服务器模拟了这样一个易受攻击的物联网设备，该服务器提供两个 API：`password` 和 `temperature`。这个 IoT 设备可以设置房间温度。要成功设置温度，我们需要向服务器的 `temperature` API 发送 HTTP 请求；请求应包含目标温度值和密码。密码是一个会定期改变的秘密，但可以通过使用 `password` API 获取。因此，为了成功设置温度，用户需要先获取密码，并将其附加到 `temperature` API 中。

密码并非用于认证的目的；它用来对抗跨站请求伪造 (CSRF) 攻击。如果没有这种保护措施，在线 CSRF 攻击就足够了；无需使用更为复杂的 DNS 重绑定攻击。为了简化起见，我们硬编码了这个密码；在实际系统中，密码会定期重新生成。

% *******************************************
% SECTION
% ******************************************* 
\section{使用容器设置实验环境}


\begin{figure}[htb]
    \centering
    \includegraphics[width=0.9\textwidth]{\commonfolder/Figs/IoT_2lans.pdf}
    \caption{实验环境设置}
    \label{rebind:fig:labsetup}
\end{figure}


在本次实验中，我们将使用六台机器。图~\ref{rebind:fig:labsetup} 展示了实验环境的设置。仅用户机器将使用虚拟机 (VM)，其他都是容器。在此设置下有两个网络：家庭网络和外部网络。家庭网络模拟了家中的典型网络。用户机器和 IoT 服务连接到该网络，此网络由路由器容器内的防火墙保护。防火墙阻止所有通往 `192.168.60.80` 的流量。因此，外部机器无法访问 IoT 设备。我们还在路由器上设置了 NAT 服务器，以便家庭网络中的机器可以访问外部（并且回复包可以返回）。

第二个网络模拟了外部世界。除了路由器外，该网络还连接了三个容器：一个作为本地 DNS 服务器，另外两个充当攻击者的名称服务器和 Web 服务器。攻击者拥有 `attacker32.com` 域名，该域名由攻击者的名称服务器容器托管。Web 服务器托管了一个恶意网站用于此攻击。

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{容器设置和命令}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/setup}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{配置用户 VM}

我们需要在用户 VM 上进行进一步的配置。

\paragraph{步骤 0. 禁用 Firefox 的 DNS over HTTPS。} 新版的 Firefox 默认启用“DNS over HTTPS”。在这种模式下，DNS 解析可能不会通过本地 DNS 服务器或 `/etc/hosts` 文件完成。这会为本次实验带来问题。我们需要禁用它。进入 `Setting`，点击 “Privacy \& Security” 标签；找到 “DNS over HTTPS” 选项，并选择“关闭”。

\paragraph{步骤 1. 减少 Firefox 的 DNS 缓存时间。} 为了减少对 DNS 服务器的负载并加快响应速度，Firefox 浏览器会缓存 DNS 结果。默认情况下，缓存的过期时间为 60 秒。这意味着我们的 DNS 重绑定攻击需要等待至少 60 秒。为了让实验更方便，我们将时间缩短为 10 秒或更少。在 URL 字段中输入 `about:config`。
点击警告页面后，我们会看到一个包含偏好名称及其值的列表。搜索 `dnsCache`，找到以下条目并更改其值：

\begin{lstlisting}
(*@\textbf{network.dnsCacheExpiration}@*): 将其值更改为 10（默认为 60）
\end{lstlisting}

在完成更改后，我们应该退出 Firefox 浏览器并重新启动它；否则更改不会生效。

\paragraph{步骤 2. 修改 `/etc/hosts`。} 我们需要向 `/etc/hosts` 文件中添加以下条目。我们将使用 `www.seedIoT32.com` 作为 IoT 服务器的名称，其 IP 地址为 `192.168.60.80`。我们需要使用超级用户权限来修改此文件（使用 `sudo`）：

\begin{lstlisting}
192.168.60.80  www.seedIoT32.com
\end{lstlisting}

在此文件中，检查是否包含任何带有 `attacker32.com` 的条目。如果有，请删除这些条目。这些条目可能在我们完成其他 SEED 实验时添加的，它们的存在将对本次实验造成问题。

现在我们可以测试 IoT 服务器了。通过用户 VM 中的以下 URL 点击浏览器。如果设置正确，我们应该能够看到恒温器，并且还可以通过拖动滑块来更改温度设置。请在实验报告中提供截图。

\begin{lstlisting}
http://www.seedIoT32.com
\end{lstlisting}


\paragraph{注意。} 我们可能在其他 SEED 实验中使用了相同的主机名 `www.attacker32.com`，因此此名称可能已经映射到不同的 IP 地址。因此，如果您没有看到预期的攻击者网站，请检查 `/etc/hosts` 文件并删除包含 `attacker32.com` 的任何条目。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{测试实验环境设置}

在配置用户 VM 后，使用 `dig` 命令获取 `www.attacker32.com` 和 `ns.attacker32.com` 的 IP 地址。您应该分别获得 `10.9.0.180` 和 `10.9.0.153`。如果未得到这些结果，则实验环境配置不正确。

我们现在可以测试攻击者的网站了。在用户 VM 中将浏览器指向以下 URL，您应该能够看到攻击者的网站。请在实验报告中提供截图。

\begin{lstlisting}
http://www.attacker32.com
\end{lstlisting}

% *******************************************
% SECTION
% ******************************************* 
\section{对 IoT 设备发起攻击}

我们准备对 IoT 设备发起攻击了。为了帮助学生了解攻击的工作原理，我们将把攻击分解为几个逐步的步骤。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务 1. 理解同源策略保护}

在本任务中，我们将进行一些实验以理解浏览器实现的同源策略保护。在用户 VM 上浏览以下三个 URL。最好是在三个不同的 Firefox 窗口中显示这些页面（而不是在三个不同的标签页中），以便所有页面都可见。

\begin{lstlisting}
URL 1: http://www.seedIoT32.com
URL 2: http://www.seedIoT32.com/change
URL 3: http://www.attacker32.com/change
\end{lstlisting}

第一个页面让我们可以看到恒温器当前的温度设置（参见图~\ref{rebinding:fig:webpages}.a），它每秒从 IoT 服务器获取一次温度值。我们应该一直保持这个页面可见，以便随时查看恒温器的温度设置。
第二个和第三个页面是相同的（参见图~\ref{rebinding:fig:webpages}.b），
只是一个是来自 IoT 服务器，另一个来自攻击者的服务器。当我们点击这两个页面上的按钮时，会向 IoT 服务器发送请求来更改其温度设置。我们应该将恒温器的温度提高到 `99` 摄氏度。

\begin{figure}[htb]
    \centering
    \includegraphics[width=0.8\textwidth]{\rebindingFigs/iot_webpages.pdf}
    \caption{来自三个 URL 的网页}
    \label{rebinding:fig:webpages}
\end{figure}

点击第二个和第三个页面上的按钮，并描述您的观察。哪个页面能够成功更改恒温器的温度？请解释原因。
要找到答案，请从 Firefox 中点击以下菜单序列。一个控制台窗口将出现，其中显示任何错误消息。提示：原因是与浏览器实施的同源策略有关。请解释为什么这种策略导致其中一个页面失败。

\begin{lstlisting}
Web Developer -> Web Console
\end{lstlisting}

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务 2. 打破同源策略保护}


从上一任务来看，由于浏览器的同源策略保护，在攻击者的页面上似乎不可能更改恒温器的温度。本次任务的目标是击败这种保护，使我们能够在该页面上设置温度。

打败同源策略保护的主要想法源于这样一个事实：政策实施基于主机名，而不基于 IP 地址，因此只要我们在 URL 中使用 `www.attacker32.com`，我们就遵守了 SOP 政策，但这并不意味着我们只能与 `www.attacker32.com` Web 服务器进行通信。

在用户浏览器向 `www.attacker32.com` 发送请求之前，它首先需要知道 `www.attacker32.com` 的 IP 地址。会从用户的机器发出一个 DNS 请求。如果本地 DNS 服务器未缓存该 IP 地址，则最终会将 DNS 请求发送到攻击者控制的 `attacker32.com` 的名称服务器。
因此，攻击者可以决定在其响应中放置什么内容。

\paragraph{步骤 1: 修改 JavaScript 代码。}
在攻击者的 Web 服务器上，在网页 \url{www.attacker32.com/change} 中运行的 JavaScript 代码存储在以下文件中：\path{/app/rebind_server/templates/js/change.js}。由于此页面来自 `www.attacker32.com` 服务器，根据同源策略，它只能与同一服务器互动。因此，我们需要将代码的第一行从 \url{http://www.seediot32.com} 更改为以下内容（我们在容器中安装了一个名为 `nano` 的简单编辑器）：

\begin{lstlisting}
let url_prefix = 'http://www.attacker32.com'
\end{lstlisting}

在完成更改后，重启攻击者的 Web 服务器容器（参见下面的命令）。然后前往用户 VM，刷新页面并再次点击按钮。您是否仍然看到控制台中的错误消息？请解释您的观察。

\begin{lstlisting}
$ docker ps
...
78359039627a  attacker-www-10.9.0.180

$ docker container restart 7835
\end{lstlisting}

\paragraph{步骤 2: 实施 DNS 重绑定。} 我们的 JavaScript 代码向 \url{www.attacker32.com} 发送请求，即这些请求会返回给攻击者的 Web 服务器。这不是我们想要的；我们希望这些请求发送到 IoT 服务器。这可以通过使用 DNS 重绑定技术来实现。首先将 \url{www.attacker32.com} 映射为攻击者 Web 服务器的 IP 地址，这样用户可以从 \url{http://www.attacker32.com/change} 获取实际页面。
在我们点击页面上的按钮之前，重新映射 \url{www.attacker32.com} 主机名到 IoT 服务器的 IP 地址，因此触发按钮的请求将发送到 IoT 服务器。这就是我们要达到的效果。

要更改 DNS 映射，学生可以修改攻击者名称服务器容器内的 \path{zone_attacker32.com} 文件。
该区域文件可以在 \texttt{/etc/bind} 文件夹中找到。下面显示了区域文件的内容。第一条记录是默认的存活时间（TTL）值 (秒)，指定响应可在 DNS 缓存中停留多久。这可能需要更改。
下面是区域文件的内容：

\begin{lstlisting}
$TTL 1000
@ IN SOA ns.attacker32.com. admin.attacker32.com. (
                2008111001
                8H
                2H
                4W
                1D)

@ IN NS ns.attacker32.com.

@ IN A 10.9.0.22
www IN A 10.9.0.22
ns IN A 10.9.0.21
* IN A 10.9.0.22
\end{lstlisting}

在更改区域文件后，运行以下命令以告知名称服务器重新加载修订的区域数据。

\begin{lstlisting}
# rndc reload attacker32.com
\end{lstlisting}

由于先前的任务执行，对于 `www.attacker32.com` 的 DNS 映射已经被本地 DNS 服务器缓存了，其将在 1000 秒后过期。为了缩短等待时间，学生可以使用以下命令清理缓存（在本地 DNS 服务器容器上）。不过这只能在攻击开始前进行。一旦攻击启动，学生就不允许再接触本地 DNS 服务器。

\begin{lstlisting}
// 在本地 DNS 服务器容器上执行
# rndc flush
\end{lstlisting}

如果完成了此任务的两个步骤，点击 \texttt{change} 页面上的按钮应该能够成功更改恒温器的温度。请在报告中提供证据以证明您的成功。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务 3. 发起攻击}

在上一个任务中，用户需要点击按钮将温度设置为危险高的值。显然，用户不太可能会这样做。本次任务的目标是自动完成这一操作。我们已经创建了一个用于此目的的网页，可以通过以下 URL 访问：

\begin{lstlisting}
http://www.attacker32.com
\end{lstlisting}

一旦您在用户 VM 中加载此页面，您应该能够看到一个带有倒计时器的页面，从 10 倒数到 0。一旦到达 0，该页面上的 JavaScript 代码将向 \url{http://www.attacker32.com} 发送设置温度请求，并然后重置定时器值为 10。学生需要使用 DNS 重绑定技术，在计时器达到 0 后，将恒温器的温度设置为 88 摄氏度。

% *******************************************
% SECTION
% *******************************************
\section{提交}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/submission}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\end{document}
```